Release 10.1A: OpenEdge Development:
ProDataSets


Special support for change conflicts

Because the ProDataSet with its independent FILL and save operations necessarily relies on an optimistic locking strategy, you need to consider what behavior you want in the event of a conflict with another change made since the ProDataSet was filled from its Data-Source. Progress supports a number of options to give you automated support for almost any circumstance.

The first decision you need to make is whether a conflict with another change should be overwritten by the current ProDataSet’s change, or rejected when Progress detects a conflict.

In some cases, you might not care whether a record has been changed by another user since it was read. Although this is certainly not typical or recommended, for some non-transactional tables that contain fields that can safely be changed independently of one another (possibly address information, for example), you might not want to reject a change if the record has been changed elsewhere. There is a PREFER-DATASET logical attribute for the Data-Source to support this option. (In the very first release of 10.0A, this attribute was called IGNORE-CURRENT-MODIFIED, and this name is still supported for compatibility, though the new name is preferred for being a clearer description of the behavior wanted.) The attribute is false by default. If PREFER-DATASET is false for the table’s Data-Source, then Progress makes the comparison between the before-table row in the database and the corresponding data-source fields before applying the change, and if there is any conflict then the change is rejected and the ERROR attribute set. If PREFER-DATASET is true, this check is not made. The ProDataSet row changes are written to the Data-Source without regard to any other changes made to the same row. As noted previously, only the database fields that are present in the ProDataSet temp-table, either implicitly or by being mapped to a field with a different name, can be compared.

You also may want to apply changes and resolve conflicts on a field by field basis. This is somewhat more expensive than either applying or rejecting all changes, but minimizes the overwriting of either your changes or another user’s changes when a conflict occurs. There is a MERGE-BY-FIELD logical attribute on the Data-Source to specify this preference. This attribute is true by default. It gives you the ability to define whether a change is wholly rejected if there are any conflicting changes, even to different fields than the ones the ProDataSet is changing.

If it is false, then if another user has changed a record, the ProDataSet changes are either entirely accepted or entirely rejected, depending on the setting of PREFER-DATASET. If it is true, then Progress “blends” the two sets of changes where possible, if they are to different fields. If it is true, then changes are applied field by field only for modified fields, and there is no conflict unless the same field has been modified both by the current update and by another transaction. A logical DATA-SOURCE-MODIFIED attribute on the temp-table buffer is set to TRUE if any field changes by another transaction are detected, regardless of whether they result in a conflict and error or not. Note that it is somewhat slower to have MERGE-BY-FIELD set to true, so it can be set to false to improve performance where a field-by-field check is really not necessary, in addition to cases where it is not wanted because of the application logic.

Here are the details of how changes are applied in the face of these attributes. In this description, “current changes” refers to modifies and deletes that are part of a ProDataSet the procedure is doing a SAVE-ROW-CHANGES on (the “current ProDataSet”). Obviously create operations do not need to check for conflicting field values. “Other changes” refers to changes made to the fields in the same rows by another user or procedure since the current ProDataSet was filled, which will be detectable by comparing the database buffers with the before-tables in the current ProDataSet.

If MERGE-BY-FIELD is false, then these are the actions:

If MERGE-BY-FIELD is true (the default), then rather than doing a wholesale buffer-copy in one direction or the other, Progress does a field by field compare of the two buffers. In this case:

The net result of all this, when PREFER-DATASET is false and MERGE-BY-FIELD is true, is that a modified row in the current ProDataSet is rejected in its entirety and causes an ERROR only when one or more of the same fields have been changed by another user. Otherwise changed fields in the current ProDataSet row are successfully written to the database. Changes made by others are copied to the ProDataSet buffer to be returned to the client, and the CHANGED flag is set.

This may all sound complicated, but in effect it means that Progress “does the right thing” based on whether you want the new change or the old one to take precedence, and whether you want to apply changes field by field or as a whole. Table 6–1 summarizes the results.

Table 6–1: Change conflict settings
PREFER-DATASET setting
MERGE-BY-FIELD setting
If field conflict…
ERROR flag
DATA-SOURCE-MODIFIED flag
What is copied to the DB
TRUE
FALSE
ProDataSet wins
FALSE
TRUE
All fields in the temp-table row.
TRUE
FALSE
ProDataSet wins
FALSE
TRUE
Changed fields only.
FALSE
TRUE
Data-Source wins
TRUE
TRUE
Only non-
conflicting fields.
FALSE
TRUE
Data-Sorceries
TRUE
TRUE
Nothing.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095